import os
import sys
import subprocess
is_windows = os.name == 'nt'

## 解析task.mk文件
def parse_commands(file_path):
    with open(file_path, 'r', encoding='utf-8', errors='replace') as file:
        lines = file.readlines()

    current_set = None
    commands = []
    current_set_all ={}
    is_get = False

    for line in lines:
        stripped_line = line.strip()

        if not stripped_line:
            # 空行，跳过
            is_get = True
            continue

        if stripped_line.endswith(':'):
            # 新的命令集开始
            if "__init__" in stripped_line:
                continue
            if current_set:
                write_script(current_set, commands)
                commands = []
            current_set = stripped_line[:-1]
            current_set_all[current_set.strip()] = ""
            is_get = False
        elif current_set:
            # 当前命令集的命令
            if not is_get and stripped_line.startswith("##"):
                current_set_all[current_set.strip()] = f"# " + stripped_line.lstrip("##").strip()
            is_get = True
            
            if is_windows and stripped_line.startswith("##"):
                stripped_line = stripped_line.replace('##', '@rem')
            commands.append(stripped_line.replace('\t', ''))

    # 处理最后一个命令集
    if current_set:
        write_script(current_set, commands)
    return current_set_all
    
## 路径转换为适合当前操作系统的路径
def convert_path_to_system(path):
    """
    将给定的路径转换为适合当前操作系统的路径。

    :param path: 给定的路径字符串
    :return: 转换后的路径字符串
    """
    # 使用 os.path.normpath 规范化路径
    norm_path = os.path.normpath(path)
    
    # 使用 os.path.join 确保路径分隔符正确
    # 分割路径成各个部分
    parts = norm_path.split(os.sep)
    
    # 重新组合路径，确保分隔符正确
    converted_path = os.path.join(*parts)
    
    return converted_path
    
# 定义一个通用的打印函数
def print_colored(text, color=None, background=None, style=None):
    if color:
        text = getattr(Fore, color.upper()) + text
    if background:
        text = getattr(Back, background.upper()) + text
    if style:
        text = getattr(Style, style.upper()) + text
    text += Style.RESET_ALL  # 重置样式
    print(text)
    
##   查找task.mk路径
def find_task_mk_in_current_directory(args):
    # 获取当前脚本所在的目录
    
    current_dir = os.getcwd()
    source_dir = os.path.dirname(os.path.abspath(__file__))
    if len(args) == 1:
        if '.mk' in args[0]:
            file_path = os.path.join(source_dir, args[0].split(':', 1)[0])
            args[0] = args[0].split(':', 1)[1]
            return file_path
    # 构建目标文件的完整路径
    task_mk_path = os.path.join(current_dir, 'task.mk')
    source_task_mk_path = os.path.join(source_dir, 'task.mk')

    # 检查文件是否存在
    if os.path.exists(task_mk_path):
        return task_mk_path
    else:
        if os.path.exists(source_task_mk_path):
               return source_task_mk_path
        else:
            return None

## 命令集名称处理
def extract_content(s):
    if s.startswith("##"):
        # 使用lstrip去除前面的'##'及可能的空格，再使用strip去除后面可能的空格
        return s.lstrip("##").strip()
    else:
        return s  # 如果字符串不是以'##'开头，则返回原字符串

## 临时sh或bat文件拆分
def write_script(name, commands):
    folder_path = convert_path_to_system(os.path.dirname(os.path.abspath(__file__))+"/tmp").replace(':', ':\\')
    os.makedirs(folder_path, exist_ok=True)
    # 处理命令集名称，如果有斜杠，取最后一个部分作为文件名
    script_name = convert_path_to_system(os.path.dirname(os.path.abspath(__file__))+"/tmp/"+name.split('/')[-1].strip() + '.sh').replace(':', ':\\')
    if is_windows:
        script_name = script_name.replace('.sh', '.bat')

    # 将命令写入到对应的shell脚本文件中
    with open(script_name, 'w',encoding='utf-8', errors='replace') as script_file:
        if not is_windows:
            script_file.write('#!/bin/bash\n\n')
        else:
            script_file.write('@echo off\n\n')
            
        for command in commands:
            script_file.write(command + '\n')

    # 设置shell脚本可执行权限
    os.chmod(script_name, 0o755)
    #print(f"Created script: {script_name}")

## 显示所有可用命令
def showallcommands(current_set_all):
    index = 0
    
    if is_windows:
        print_colored("Select a Task:", color='yellow', style='bright')
    else:
        # 定义黄色前景色和重置属性的ANSI转义码
        YELLOW = '\033[93m'
        RESET = '\033[0m'
        print(f"{YELLOW}Select a Task:{RESET}")

    for key, value in current_set_all.items():
        if key == "__init__":
            continue
        index = index + 1
        print((f"      {index}. {key}").ljust(40)+f"{value}")
def copy_file_manual(src, dst):
    try:
        with open(src, 'rb') as src_file:
            with open(dst, 'wb') as dst_file:
                while True:
                    chunk = src_file.read(1024)  # 读取 1024 字节
                    if not chunk:
                        break
                    dst_file.write(chunk)
    except FileNotFoundError:
        print(f"错误：源文件 {src} 不存在")
    except PermissionError:
        print(f"错误：没有权限访问文件 {src} 或 {dst}")
    except Exception as e:
        print(f"发生未知错误: {e}")
        
def run_bat_or_sh(key):
    if is_windows:
        bat_file = convert_path_to_system(os.path.dirname(os.path.abspath(__file__))+"/tmp/"+key.split('/')[-1].strip() + '.bat').replace(':', ':\\')
        des_file = "E:\\tmp.bat"
    else:
        bat_file = convert_path_to_system(os.path.dirname(os.path.abspath(__file__))+"/tmp/"+key.split('/')[-1].strip() + '.sh').replace(':', ':\\')
    copy_file_manual(bat_file, des_file)
    #print(bat_file)
    #print(des_file)
    # process = subprocess.Popen(bat_file, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding='utf-8')
    # # 实时读取输出
    # while True:
        # output = process.stdout.readline().strip()
        # if output == '' and process.poll() is not None:
            # break
        # if output:
            # print(output.strip())
    # # 获取剩余的输出
    # stdout, stderr = process.communicate()
    # if len(f"{stdout}") > 0:
        # print(f"{stdout}")
    # if len(f"{stderr}") > 0:
        # # 打印标准错误
        # print(f"{stderr}")
  
def runcommands(comm, current_set_all):
    #run_bat_or_sh("__init__")
    key = ""
    if comm.isdigit():
        keys = list(current_set_all.keys())
        key = keys[int(comm)-1]

    else:
        for name, value in current_set_all.items():
            if name.find('/') != -1:
                parts = name.split("/")
                if comm == parts[0].strip() or comm == parts[1].strip():
                    key = parts[1].strip()
            else:
                if comm == name:
                    key = name
    run_bat_or_sh(key)    


if __name__ == "__main__":
    args = sys.argv[1:]  # 忽略第一个元素，即脚本名称
    if is_windows:
        from colorama import Fore, Back, Style, init
        init(autoreset=True)  # 初始化 colorama
    file_path = find_task_mk_in_current_directory(args)  # 指定包含命令集的文本文件路径
    #print(file_path)
    #print(len(args))
    current_set_all = parse_commands(file_path)
    if len(args) < 1:
       showallcommands(current_set_all)
       exit()
    if len(args) == 1 and len(args[0]) > 0:
        runcommands(args[0], current_set_all)
    else:
        showallcommands(current_set_all)